from collect_baostock_data import StockBase
from const import PROJ_HOME
from date_util import now_date_fmt

"""

@author: tongzhenguo

@time: 2020/9/14 上午10:46

@desc:

自己实现一些学到的均线策略
"""


class MaStrategy(StockBase):
    def __init__(self, input, output, start_date=None, end_date=None):
        super().__init__()
        self.obj = StockBase()
        self.start_date = start_date if start_date else "2021-03-01"
        self.end_date = end_date if end_date else now_date_fmt("YYYY-MM-DD")

    def granville_rule(self):
        """格兰维尔八大交易法则"""
        for row in self.obj.stock_data[["name", "code"]].values:
            try:
                name = row[0]
                print("股票:%s" % name)
                code = row[1]
                stock_data = self.obj.get_history_k_data(code, name, self.start_date, self.end_date)
                ma_list = [20]
                # 计算简单算术移动平均线MA - 注意：stock_data['close']为股票每天的收盘价
                for ma in ma_list:
                    col_name = 'MA_' + str(ma)
                    stock_data[col_name] = stock_data['close'].rolling(ma).mean()
                    stock_data[col_name] = stock_data[col_name].apply(lambda _: round(_, 2))
                close_price_array = stock_data["close"].tail(2).values
                t_1_ma_20 = stock_data["MA_20"].tail(2).values[0]
                t_2_close_price = float(close_price_array[0])
                t_1_close_price = float(close_price_array[1])
                close_price_array = stock_data["close"].tail(20).values
                t_20_max_close_price = float(max(list(close_price_array)))
                # 低价金叉买入:T-2收盘低于均线,T-1收盘突破均线
                if t_2_close_price < t_1_ma_20 <= t_1_close_price:
                    print("满足规则1--低价金叉买入:T-2收盘低于均线,T-1收盘突破均线!")
                # 假破位拉回买入:前20天最高价大于ma20,t-2收盘低于均线,T-1收盘突破均线
                elif t_20_max_close_price > t_1_ma_20 and t_2_close_price < t_1_ma_20 <= t_1_close_price:
                    print("满足规则2--假破位拉回买入:前20天最高价大于ma20,t-2收盘低于均线,T-1收盘突破均线!")
                # 回调有效支撑:股价回到均线附近，卖出减少，买入增加
                elif t_1_ma_20 * 0.95 < t_1_close_price < t_1_ma_20 * 1.05 and t_2_close_price > t_1_close_price:
                    print("满足规则3--回调有效支撑:股价回到均线附近，卖出减少，买入增加!")
                # 高位死叉卖出:14天内一直下跌或涨幅不大于1%,且跌破均线
                window = 7
                i = 2 * window
                l = stock_data["close"].tail(i).to_list()
                l2 = stock_data["MA_20"].tail(i).to_list()
                t_20_price_list_ = [float(ll) for ll in l]
                t_20_ma_list_ = [float(ll) for ll in l2]
                while 1.01 * t_20_price_list_[-i + 1] >= t_20_price_list_[-i] >= t_20_price_list_[-i + 1]:
                    i -= 1
                if i == 0 and t_1_ma_20 > t_1_close_price:
                    print("满足规则5--高位死叉卖出:14天内一直下跌或涨幅不大于1%,且跌破均线")
                # 回抽压力位卖出:14天内一直回升或跌幅不大于1%,且但未突破均线
                i = 2 * window
                while 1.01 * t_20_price_list_[-i + 1] <= t_20_price_list_[-i] <= t_20_price_list_[-i + 1] and t_20_ma_list_[
                    -i + 1] > t_20_ma_list_[-i]:
                    i -= 1
                if i == 0 and t_1_ma_20 > t_1_close_price:
                    print("满足规则6--回抽压力位卖出:14天内一直回升或跌幅不大于1%,且但未突破均线")
                # 假突破逢高卖出:股价虽反弹突破平均线，但不久又跌到平均线之下，而此时平均线仍在下跌时
                i = 2 * window
                while t_20_ma_list_[-i + 1] > t_20_ma_list_[-i]:
                    i -= 1
                if i == 0 and (t_2_close_price >= t_1_ma_20 or t_1_close_price >= t_1_ma_20):
                    print("满足规则7--假突破逢高卖出:股价虽反弹突破平均线，但不久又跌到平均线之下，而此时平均线仍在下跌时")
                # 正乖离过大卖出:高于ma20百分之十
                elif (t_1_close_price - t_1_ma_20) / t_1_ma_20 >= 0.1:
                    print("满足规则8--正乖离过大卖出:高于ma20百分之十")
            except :
                pass


if __name__ == "__main__":
    input_path = PROJ_HOME + "/data/baostock"
    output_path = PROJ_HOME + "/data/baostock_with_pe_ttl"
    ms = MaStrategy(input_path, output_path)
    ms.granville_rule()
